#include "StdAfx.h"
#include "FileOperation.h"

BOOL FindFiles(LPCTSTR lpszStartDir, BOOL bIncSubDir, FILE_FIND_CALLBACK lpFileCallBack, FOLDER_FIND_CALLBACK lpFolderCallBack, LPVOID lpCallbackParam)
{
	WIN32_FIND_DATA find = {0};
	HANDLE hFind = INVALID_HANDLE_VALUE;
	CString csFindPath;
	CString csSubDirPath;
	BOOL bRet = TRUE;

	csFindPath = lpszStartDir;
	if (csFindPath.Right(1) != _T("\\"))
	{
		csFindPath += _T("\\");
	}
	else
	{
		TRACE(_T("Dir end with \\ is not allowd!\r\n"));
		return FALSE;
	}

	csFindPath += _T("*");

	hFind = FindFirstFile(csFindPath, &find);
	if (hFind == INVALID_HANDLE_VALUE)
	{
		return FALSE;
	}

	while (FindNextFile(hFind, &find))
	{
		if (find.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
		{
			//Dir
			if (!bIncSubDir)
			{
				continue;
			}

			// ".." and "."
			if (find.cFileName[0] == _T('.') 
				&& (find.cFileName[1] == _T('\0') 
				|| (find.cFileName[1] == _T('.') 
					&& find.cFileName[2] == _T('\0'))))
			{
				continue;
			}

			if (!lpFolderCallBack(lpCallbackParam, lpszStartDir, &find))
			{
				bRet = FALSE;
				break;
			}

			csSubDirPath = csFindPath.Left(csFindPath.GetLength()-1);
			csSubDirPath += find.cFileName;
			if (!FindFiles(csSubDirPath, bIncSubDir, lpFileCallBack, lpFolderCallBack, lpCallbackParam))
			{
				bRet = FALSE;
				break;
			}
		}
		else
		{
			//File
			if (!lpFileCallBack(lpCallbackParam, lpszStartDir, &find))
			{
				bRet = FALSE;
				break;
			}
		}
	}

	if (hFind != INVALID_HANDLE_VALUE)
	{
		FindClose(hFind);
		hFind = INVALID_HANDLE_VALUE;
	}

	return bRet;
}
